package com.gitee.huanminabc.fastboot.load.stage.poststage;

import com.gitee.huanminabc.jcommon.multithreading.executor.ThreadFactoryUtil;
import com.gitee.huanminabc.jcommon.reflect.ReflectPath;
import com.gitee.huanminabc.fastboot.context.AppContext;
import com.gitee.huanminabc.fastboot.context.AppContextUtil;
import com.gitee.huanminabc.fastboot.load.hook.ContainerInitCallBackFinishLifecycleHook;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Method;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 容器调用初始化函数
 * 1. 必须等ConfigValueInjectionStage和DependencyInjectionStage完成后才执行
 *
 * @description:
 * @author: huanmin
 * @create: 2025-04-17 15:04
 **/
@Slf4j
public class ContainerInitCallBackStage implements AppLoadPostStage {
    public static volatile boolean dependencyInjectionStageOk = false;
    public static volatile boolean configValueInjectionStageOk = false;
    public final static Object lock = new Object();

    @Override
    public void run() {
        while (!dependencyInjectionStageOk || !configValueInjectionStageOk) {
            try {
                synchronized (lock) {
                    lock.wait();
                }
            } catch (InterruptedException e) {
                log.error("容器初始化函数等待失败");
                System.exit(1);
            }
        }
        CountDownLatch countDownLatch = new CountDownLatch( AppContext.containerInitMethods.size());
        ThreadPoolExecutor executor = ThreadFactoryUtil.getDefaultExecutor();
        for (Method containerInitMethod : AppContext.containerInitMethods) {
            Class<?> declaringClass = containerInitMethod.getDeclaringClass();
            Object bean = AppContextUtil.getBean(declaringClass);
            if (bean==null){
                log.error("容器初始化函数:{}执行失败,没有找到对应的bean:{}", ReflectPath.getMethod(containerInitMethod), declaringClass.getName());
                System.exit(1);
            }
            executor.execute(()->{
                try {
                    containerInitMethod.invoke(bean);
                } catch (Exception e) {
                    log.error("容器初始化函数:{}执行失败", ReflectPath.getMethod(containerInitMethod), e);
                    System.exit(1);
                }finally {
                    countDownLatch.countDown();
                }
            });
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
                log.error("ContainerInitCallBackStage load fail", e);
                System.exit(1);
        }
        log.debug("ContainerInitCallBackStage load success");
        new ContainerInitCallBackFinishLifecycleHook().run();
    }
}
